<template>
	<div class="app-container">
		<div class="search-container">
			<el-form ref="queryFormRef" :model="queryParams" :inline="true">
				<el-form-item label="关键字" prop="keywords">
					<el-input v-model="queryParams.keywords" placeholder="菜单名称" clearable @keyup.enter="handleQuery" />
				</el-form-item>
				<el-form-item>
					<el-button type="primary" @click="handleQuery"
						><template #icon><i class="i-ep-search" /></template>搜索</el-button
					>
					<el-button @click="resetQuery">
						<template #icon>
							<i class="i-ep-refresh" />
						</template>
						重置</el-button
					>
				</el-form-item>
			</el-form>
		</div>

		<el-card shadow="never" class="table-container">
			<template #header>
				<el-button type="success" @click="openDialog(0)">
					<template #icon>
						<i class="i-ep-plus" />
					</template>
					新增</el-button
				>
			</template>

			<el-table
				v-loading="loading"
				:data="menuList"
				highlight-current-row
				row-key="path"
				:expand-row-keys="['1']"
				:tree-props="{
					children: 'children',
					hasChildren: 'hasChildren',
				}"
				@row-click="onRowClick"
			>
				<el-table-column label="菜单名称" min-width="200">
					<template #default="{ row }">
						<i :class="'i-ep-' + row.meta.icon" />
						{{ row.meta.title }}
					</template>
				</el-table-column>

				<el-table-column label="类型" align="center" min-width="120">
					<template #default="{ row }">
						<el-tag v-if="row.type === MenuTypeEnum.CATALOG" type="warning">目录</el-tag>
						<el-tag v-if="row.type === MenuTypeEnum.MENU" type="success">菜单</el-tag>
						<el-tag v-if="row.type === MenuTypeEnum.BUTTON" type="danger">按钮</el-tag>
						<el-tag v-if="row.type === MenuTypeEnum.EXTLINK" type="info">外链</el-tag>
					</template>
				</el-table-column>

				<el-table-column label="路由路径" align="left" min-width="200" prop="path" />

				<el-table-column label="组件路径" align="left" min-width="250" prop="component" />

				<el-table-column label="权限标识" align="center" min-width="200" prop="perm" />

				<el-table-column label="状态" align="center" width="80">
					<template #default="{ row }">
						<el-tag v-if="!row.isHide" type="success">显示</el-tag>
						<el-tag v-else type="info">隐藏</el-tag>
					</template>
				</el-table-column>

				<el-table-column label="排序" align="center" width="80" prop="sort" />

				<el-table-column fixed="right" align="center" label="操作" width="220">
					<template #default="{ row }">
						<el-button v-if="row.type == 'CATALOG' || row.type == 'MENU'" type="primary" link size="small" @click.stop="openDialog(row.id)">
							<i class="i-ep-plus" />新增
						</el-button>

						<el-button type="primary" link size="small" @click.stop="openDialog(undefined, row.id)">
							<i class="i-ep-edit" />编辑
						</el-button>
						<el-button type="primary" link size="small" @click.stop="handleDelete(row.id)"
							><i class="i-ep-delete" />
							删除
						</el-button>
					</template>
				</el-table-column>
			</el-table>
		</el-card>

		<el-dialog v-model="dialog.visible" :title="dialog.title" destroy-on-close append-to-body width="1000px" top="5vh" @close="closeDialog">
			<el-form ref="menuFormRef" :model="formData" :rules="rules" label-width="160px">
				<el-form-item label="父级菜单" prop="parentId">
					<el-tree-select
						v-model="formData.parentId"
						placeholder="选择上级菜单"
						:data="menuOptions"
						filterable
						check-strictly
						:render-after-expand="false"
					/>
				</el-form-item>

				<el-form-item label="菜单名称" prop="name">
					<el-input v-model="formData.name" placeholder="请输入菜单名称" />
				</el-form-item>

				<el-form-item label="菜单类型" prop="type">
					<el-radio-group v-model="formData.type" @change="onMenuTypeChange">
						<el-radio label="CATALOG">目录</el-radio>
						<el-radio label="MENU">菜单</el-radio>
						<el-radio label="BUTTON">按钮</el-radio>
						<el-radio label="EXTLINK">外链</el-radio>
					</el-radio-group>
				</el-form-item>

				<el-form-item v-if="formData.type == 'EXTLINK'" label="外链地址" prop="path">
					<el-input v-model="formData.path" placeholder="请输入外链完整路径" />
				</el-form-item>

				<el-form-item v-if="formData.type == MenuTypeEnum.CATALOG || formData.type == MenuTypeEnum.MENU" label="路由路径" prop="path">
					<el-input v-if="formData.type == MenuTypeEnum.CATALOG" v-model="formData.path" placeholder="system" />
					<el-input v-else v-model="formData.path" placeholder="user" />
				</el-form-item>

				<!-- 组件页面完整路径 -->
				<el-form-item v-if="formData.type == MenuTypeEnum.MENU" label="页面路径" prop="component">
					<el-input v-model="formData.component" placeholder="system/user/index" style="width: 95%">
						<template v-if="formData.type == MenuTypeEnum.MENU" #prepend>src/views/</template>
						<template v-if="formData.type == MenuTypeEnum.MENU" #append>.vue</template>
					</el-input>
				</el-form-item>

				<el-form-item v-if="formData.type !== MenuTypeEnum.BUTTON" prop="visible" label="显示状态">
					<el-radio-group v-model="formData.visible">
						<el-radio :label="1">显示</el-radio>
						<el-radio :label="0">隐藏</el-radio>
					</el-radio-group>
				</el-form-item>

				<el-form-item v-if="formData.type === MenuTypeEnum.CATALOG" label="根目录始终显示">
					<template #label>
						<div>
							根目录始终显示
							<el-tooltip placement="bottom" effect="light">
								<template #content>是：根目录只有一个子路由显示目录 <br />否：根目录只有一个子路由不显示目录，只显示子路由 </template>
								<i class="i-ep-QuestionFilled inline-block"></i>
							</el-tooltip>
						</div>
					</template>

					<el-radio-group v-model="formData.alwaysShow">
						<el-radio :label="1">是</el-radio>
						<el-radio :label="0">否</el-radio>
					</el-radio-group>
				</el-form-item>

				<el-form-item v-if="formData.type === MenuTypeEnum.MENU" label="是否缓存">
					<el-radio-group v-model="formData.keepAlive">
						<el-radio :label="1">是</el-radio>
						<el-radio :label="0">否</el-radio>
					</el-radio-group>
				</el-form-item>

				<el-form-item label="排序" prop="sort">
					<el-input-number v-model="formData.sort" style="width: 100px" controls-position="right" :min="0" />
				</el-form-item>

				<!-- 权限标识 -->
				<el-form-item v-if="formData.type == MenuTypeEnum.BUTTON" label="权限标识" prop="perm">
					<el-input v-model="formData.perm" placeholder="sys:user:add" />
				</el-form-item>

				<el-form-item v-if="formData.type !== MenuTypeEnum.BUTTON" label="图标" prop="icon">
					<!-- 图标选择器 -->
					<!-- <icon-select v-model="formData.icon" /> -->
					图标选择器
				</el-form-item>

				<el-form-item v-if="formData.type == MenuTypeEnum.CATALOG" label="跳转路由">
					<el-input v-model="formData.redirect" placeholder="跳转路由" />
				</el-form-item>
			</el-form>

			<template #footer>
				<div class="dialog-footer">
					<el-button type="primary" @click="submitForm">确 定</el-button>
					<el-button @click="closeDialog">取 消</el-button>
				</div>
			</template>
		</el-dialog>
	</div>
</template>

<script setup lang="ts">
	defineOptions({
		name: 'MenuMange',
		inheritAttrs: false,
	})

	import { MenuQuery, MenuForm, MenuVO } from '@/api/menu/types'
	import { listMenus, getMenuForm, getMenuOptions, addMenu, deleteMenu, updateMenu } from '@/api/menu'

	import { MenuTypeEnum } from '@/enums/MenuTypeEnum'

	import { useAuthStore } from '@/store'

	const authStore = useAuthStore()
	const queryFormRef = ref()
	const menuFormRef = ref(ElForm)

	const loading = ref(false)
	const dialog = reactive({
		title: '',
		visible: false,
	})

	const queryParams = reactive<MenuQuery>({})
	const menuList = computed(() => authStore.menuList)

	const menuOptions = ref<OptionType[]>([])

	const formData = reactive<MenuForm>({
		parentId: 0,
		visible: 1,
		sort: 1,
		type: MenuTypeEnum.MENU,
		alwaysShow: 0,
		keepAlive: 0,
	})

	const rules = reactive({
		parentId: [{ required: true, message: '请选择顶级菜单', trigger: 'blur' }],
		name: [{ required: true, message: '请输入菜单名称', trigger: 'blur' }],
		type: [{ required: true, message: '请选择菜单类型', trigger: 'blur' }],
		path: [{ required: true, message: '请输入路由路径', trigger: 'blur' }],

		component: [{ required: true, message: '请输入组件路径', trigger: 'blur' }],
		visible: [{ required: true, message: '请输入路由路径', trigger: 'blur' }],
	})

	// 选择表格的行菜单ID
	const selectedRowMenuId = ref<number | undefined>()

	const menuCacheData = reactive({
		type: '',
		path: '',
	})

	/**
	 * 查询
	 */
	function handleQuery() {
		// 重置父组件
		// loading.value = true
		// listMenus(queryParams)
		// 	.then(({ data }) => {
		// 		menuList.value = data
		// 	})
		// 	.then(() => {
		// 		loading.value = false
		// 	})
	}

	/** 重置查询 */
	function resetQuery() {
		queryFormRef.value.resetFields()
		handleQuery()
	}

	/**行点击事件 */
	function onRowClick(row: MenuVO) {
		selectedRowMenuId.value = row.id
	}

	/**
	 * 打开表单弹窗
	 *
	 * @param parentId 父菜单ID
	 * @param menuId 菜单ID
	 */
	function openDialog(parentId?: number, menuId?: number) {
		getMenuOptions()
			.then(({ data }) => {
				menuOptions.value = [{ value: 0, label: '顶级菜单', children: data }]
			})
			.then(() => {
				dialog.visible = true
				if (menuId) {
					dialog.title = '编辑菜单'
					getMenuForm(menuId).then(({ data }) => {
						Object.assign(formData, data)
						menuCacheData.type = data.type
						menuCacheData.path = data.path ?? ''
					})
				} else {
					dialog.title = '新增菜单'
					formData.parentId = parentId
				}
			})
	}

	/** 菜单类型切换事件处理 */
	function onMenuTypeChange() {
		// 如果菜单类型改变，清空路由路径；未改变在切换后还原路由路径
		if (formData.type !== menuCacheData.type) {
			formData.path = ''
		} else {
			formData.path = menuCacheData.path
		}
	}

	/** 菜单保存提交 */
	function submitForm() {
		menuFormRef.value.validate((isValid: boolean) => {
			if (isValid) {
				const menuId = formData.id
				if (menuId) {
					updateMenu(menuId, formData).then(() => {
						ElMessage.success('修改成功')
						closeDialog()
						handleQuery()
					})
				} else {
					addMenu(formData).then(() => {
						ElMessage.success('新增成功')
						closeDialog()
						handleQuery()
					})
				}
			}
		})
	}

	/** 删除菜单 */
	function handleDelete(menuId: number) {
		if (!menuId) {
			ElMessage.warning('请勾选删除项')
			return false
		}

		ElMessageBox.confirm('确认删除已选中的数据项?', '警告', {
			confirmButtonText: '确定',
			cancelButtonText: '取消',
			type: 'warning',
		})
			.then(() => {
				deleteMenu(menuId).then(() => {
					ElMessage.success('删除成功')
					handleQuery()
				})
			})
			.catch(() => ElMessage.info('已取消删除'))
	}

	/** 关闭弹窗 */
	function closeDialog() {
		dialog.visible = false
		resetForm()
	}

	/** 重置表单 */
	function resetForm() {
		menuFormRef.value.resetFields()
		menuFormRef.value.clearValidate()

		formData.id = undefined
		formData.parentId = 0
		formData.visible = 1
		formData.sort = 1
		formData.perm = undefined
		formData.component = undefined
		formData.path = undefined
		formData.redirect = undefined
		formData.alwaysShow = undefined
		formData.keepAlive = undefined
	}

	onMounted(() => {
		handleQuery()
	})
</script>
